package zdream.pmfield.stage.buff.ability;

import zdream.pmfield.data.foe.MoveAdditionalEffects;
import zdream.pmfield.data.foe.Type;
import zdream.pmfield.stage.director.AttackContext;
import zdream.pmfield.stage.director.FixPair;
import zdream.pmfield.stage.director.Hooks;
import zdream.pmfield.stage.object.FoeActor;
import zdream.pmfield.stage.object.StageMove;

import static zdream.pmfield.stage.director.HookType.ON_CHECK_TYPE_FIXED;

/**
 * 虫族效果:
 * <li>对草增加 0.5 级的抗性
 * <li>对火、风减少 0.5 级的抗性
 * <li>对鸟族 {@link BirdGroupBuff} 使用恶系技能伤害减少 0.5 级
 * <li>修改恶对草、光的克制等级为 +1 级
 * </li>
 *
 * @author Zdream
 * @date 2023-12-21
 * @since 0.0.1
 */
public class BugGroupBuff extends AbilityBuff {
	public static final String CATEGORY = MoveAdditionalEffects.A_BUG_GROUP;

	public BugGroupBuff(BuffDescription description) {
		super(description);
	}

	@Override
	public String getCategory() {
		return CATEGORY;
	}

	@Override
	public String toString() {
		return "虫族";
	}

	@Override
	public void init() {
		onHook(ON_CHECK_TYPE_FIXED)
				.handle(this::checkTypeFixedWhenIAmDefender)
				.buildAndSave();
		onHook(ON_CHECK_TYPE_FIXED)
				.handle(this::checkTypeFixedWhenIAmAttacker)
				.withPriority(-600)
				.buildAndSave();
	}

	private void checkTypeFixedWhenIAmDefender(Hooks.HookContext rawContext) {
		Hooks.AttackHookContext context = rawContext.as();
		final AttackContext attackContext = context.attackContext;
		final AttackContext.AttackContextItem item = attackContext.findAttackItemForDefender(target);

		if (item == null) {
			return;
		}

		final StageMove move = attackContext.currentMove;
		if (move.hasType(Type.GRASS)) {
			item.typeFixPairs.add(FixPair.ofDefender(0.5f * move.weightOfType(Type.GRASS), (byte)-1, CATEGORY));
		}
		if (move.hasType(Type.FIRE)) {
			item.typeFixPairs.add(FixPair.ofDefender(0.5f * move.weightOfType(Type.FIRE), (byte)1, CATEGORY));
		}
		if (move.hasType(Type.WIND)) {
			item.typeFixPairs.add(FixPair.ofDefender(0.5f * move.weightOfType(Type.WIND), (byte)1, CATEGORY));
		}
	}

	private void checkTypeFixedWhenIAmAttacker(Hooks.HookContext rawContext) {
		Hooks.AttackHookContext context = rawContext.as();
		final AttackContext attackContext = context.attackContext;
		if (!attackContext.hasAttacker(target)) {
			return;
		}

		StageMove move = attackContext.currentMove;
		if (!move.hasType(Type.DARK)) {
			return;
		}

		float darkWeight = move.weightOfType(Type.DARK);

		for (AttackContext.AttackContextItem item : attackContext.items) {
			final FoeActor targetFoe = item.targetFoe;
			if (targetFoe == null) {
				continue;
			}

			item.typeFixPairs.stream()
					.filter(FixPair::isForType)
					.map(FixPair::asType)
					.filter(pair -> pair.attack == Type.DARK)
					.filter(pair -> pair.defense == Type.GRASS || pair.defense == Type.LIGHT)
					.forEach(pair -> pair.fixRateLevel = 1);

			if (targetFoe.hasBuff(BirdGroupBuff.CATEGORY)) {
				item.typeFixPairs.add(FixPair.of(
					new String[] {CATEGORY},
					new String[] {BirdGroupBuff.CATEGORY},
					0.5f * darkWeight,
					(byte)-1
				));
			}
		}
	}
}
